import random
import logging
from .base import BaseChannel



logger = logging.getLogger('TopChannel')



class TopologyChannel(BaseChannel):
    
    def __init__(self, env, top, delay, collision_prob):
        self.env = env
        self.top = top
        self.delay = delay
        self.collision_prob = collision_prob
    
    def transmit(self, sender, packet):
        sender.last_ts = self.env.now
        for n in self.top.neighbors(sender):
            self.env.process(self.deliver_start(n, sender, packet))

    def deliver_start(self, receiver, sender, packet):

        logger.debug(f'{self.env.now:.6f} {sender.id} deliver to {receiver.id} {packet}')
        
        # Delay time
        yield self.env.timeout(self.delay)
        
        # Check conflict and send
        current_time = self.env.now
        concurrent = False
        for n in self.top.neighbors(sender):
            # If other linked node is send
            if current_time - n.last_ts < 2 *self.delay:
                concurrent = True
                logger.warning(f'{self.env.now:.6f} {sender.id} conflict with {n.id}')
                break

        # Random collision
        if concurrent and random.random() < self.collision_prob:
            return
        
        receiver.phy.rx(sender, packet)